﻿#include "FITKAbaqusPart.h"
#include "FITKDataCase.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMeshPartVTK.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaEngineeringFeature.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialOrientation.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBeamOrientation.h"
#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Interface/FITKInterfaceModel/FITKCoordinateSystem.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKSectionAssign.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoShapeAgent.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoCommand.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoImportedPart.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"

#include "FITK_Interface/FITKInterfaceMeshGen/FITKMeshGenInterface.h"
#include "FITK_Interface/FITKInterfaceMeshGen/FITKAbstractMeshingParameter.h"

namespace AbaqusData
{

    FITKAbaqusPart::FITKAbaqusPart()
    {
        //初始化
        int id = this->getDataObjectID();
        _mesh = new Interface::FITKAbaMeshPartVTK;
        _mesh->setParentDataID(id);
        _setSurfManager = new Interface::FITKComponentManager;
        _setSurfManager->setParentDataIDM(id);
        _sectionAssignManager = new Interface::FITKSectionAssignManager;
        _sectionAssignManager->setParentDataIDM(id);
        _engineeringFeature = new Interface::FITKAbaPartEngineeringFeature;
        _engineeringFeature->setParentDataID(id);
        //局部坐标系
        _csysManager = new Interface::FITKCoordinateSystemManager;
        _csysManager->setParentDataIDM(id);
        //材料方向管理器
        _materialOrientationManager = new Interface::FITKAbaMaterialOrientationManager;
        _materialOrientationManager->setParentDataIDM(id);
        //Beam方向管理器
        _beamOrientationManager = new Interface::FITKAbaBeamOrientationManager;
        _beamOrientationManager->setParentDataIDM(id);

        //网格划分参数初始化
        _surfaceMeshingParameter = new Interface::FITKSurfaceMeshingParameter;
        _volumeMeshingParameter = new Interface::FITKVolumeMeshingParameter;
    }

    FITKAbaqusPart::~FITKAbaqusPart()
    {
        //内存释放
        if (_mesh != nullptr) delete _mesh;
        if (_setSurfManager != nullptr) delete _setSurfManager;
        if (_sectionAssignManager != nullptr) delete _sectionAssignManager;
        if (_engineeringFeature != nullptr) delete _engineeringFeature;
        if (_csysManager != nullptr) delete _csysManager;
        if (_materialOrientationManager != nullptr) delete _materialOrientationManager;
        if (_beamOrientationManager != nullptr) delete _beamOrientationManager;
        if (_surfaceMeshingParameter != nullptr) delete _surfaceMeshingParameter;
        if (_volumeMeshingParameter != nullptr) delete _volumeMeshingParameter;
    }

    Interface::FITKModelEnum::AbsModelType FITKAbaqusPart::getAbsModelType()
    {
        //几何网格混合类型
        return Interface::FITKModelEnum::AMTMIX;
    }

    Interface::FITKAbaMeshPartVTK* FITKAbaqusPart::getMesh()
    {
        //网格
        return _mesh;
    }

    Interface::FITKComponentManager* FITKAbaqusPart::getComponentManager()
    {
        //集合管理器
        return _setSurfManager;
    }

    Interface::FITKModelSet* FITKAbaqusPart::getModelSetByMember(Interface::FITKModelEnum::FITKModelSetType t, const QList<int> &member)
    {
        auto manager = this->getComponentManager();
        if (manager == nullptr) return nullptr;
        return manager->getModelSetByMember(t, this->getDataObjectID(), member);
    }

    Interface::FITKSectionAssignManager* FITKAbaqusPart::getSectionAssignManager()
    {
        return _sectionAssignManager;
    }

    Interface::FITKAbaPartEngineeringFeature* FITKAbaqusPart::getPartEngineerFeature()
    {
        return _engineeringFeature;
    }

    Interface::FITKCoordinateSystemManager* FITKAbaqusPart::getCoordinateSystemManager()
    {
        return _csysManager;
    }

    Interface::FITKAbaMaterialOrientationManager* FITKAbaqusPart::getMaterialOrientationManager()
    {
        return _materialOrientationManager;
    }

    Interface::FITKAbaBeamOrientationManager* FITKAbaqusPart::getBeamOrientationManager()
    {
        return _beamOrientationManager;
    }

    Interface::FITKSurfaceMeshingParameter* FITKAbaqusPart::getSurfaceMeshParameter()
    {
        return _surfaceMeshingParameter;
    }

    Interface::FITKVolumeMeshingParameter* FITKAbaqusPart::getVolumeMeshParameter()
    {
        return _volumeMeshingParameter;
    }

    Interface::FITKModelEnum::FITKModelDim FITKAbaqusPart::getModelDim()
    {
        // 优先获取几何维度。
        Interface::FITKAbsGeoImportedPart* cmdPart = dynamic_cast<Interface::FITKAbsGeoImportedPart*>(getGeoCommandObj());
        if (cmdPart)
        {
            // 获取首个模型命令获取维度即可。
            Interface::FITKAbsGeoCommand* firstCmd = cmdPart->getDataByIndex(0);
            if (firstCmd)
            {
                int geoDim = firstCmd->getShapeAgent()->getDim();
                switch (geoDim)
                {
                case 0:
                    return Interface::FITKModelEnum::FMD0;
                case 1:
                    return Interface::FITKModelEnum::FMD1;
                case 2:
                    return Interface::FITKModelEnum::FMD2;
                case 3:
                    return Interface::FITKModelEnum::FMD3;
                default:break;
                }
            }
        }

        // 无几何则获取网格维度。
        if (_mesh && _mesh->getElementCount())
        {
            Interface::FITKModelEnum::FITKMeshDim dm = _mesh->getMeshDim();
            switch (dm)
            {
            case Interface::FITKModelEnum::FMDimD0:
                return Interface::FITKModelEnum::FMD0;
            case Interface::FITKModelEnum::FMDimD1:
                return Interface::FITKModelEnum::FMD1;
            case Interface::FITKModelEnum::FMDimD2:
                return Interface::FITKModelEnum::FMD2;
            case Interface::FITKModelEnum::FMDimD3:
                return Interface::FITKModelEnum::FMD3;
            default:break;
            }
        }

        // 几何与网格均不存在则返回空。
        return Interface::FITKModelEnum::FMDNone;
    }

    bool FITKAbaqusPart::getPointCoor(int pointID, double* coor, int modelIndex /*= 0*/)
    {
        //获取点坐标，网格点
        Core::FITKNode* node = _mesh->getNodeByID(pointID);
        if (node == nullptr) return false;
        node->getCoor(coor);
        return true;
    }

    void FITKAbaqusPart::setGeoCommand(const int cid)
    {
        Interface::FITKAbsGeoCommand* cmd = FITKDATAREPO->getTDataByID<Interface::FITKAbsGeoCommand>(cid);
        if (cmd == nullptr) return;
        _geoCommandID = cmd->getDataObjectID();
    }

    Interface::FITKAbsGeoCommand* FITKAbaqusPart::getGeoCommandObj()
    {
        return FITKDATAREPO->getTDataByID<Interface::FITKAbsGeoCommand>(_geoCommandID);
    }

    void FITKAbaqusPart::setAbsDataID(const int id)
    {
        Interface::FITKAbstractModel::setAbsDataID(id);
        if (_mesh) _mesh->setParentDataID(id);
        if (_setSurfManager) _setSurfManager->setParentDataIDM(id);
        if (_sectionAssignManager) _sectionAssignManager->setParentDataIDM(id);
        if (_engineeringFeature) _engineeringFeature->setParentDataID(id);
        if (_csysManager) _csysManager->setParentDataIDM(id);
        if (_materialOrientationManager) _materialOrientationManager->setParentDataIDM(id);
    }

    void FITKAbaqusPartManager::removeDataObj(Core::FITKAbstractDataObject* obj)
    {
        if (obj == nullptr) return;
        const int partID = obj->getDataObjectID();
        const int caseID = this->getMParentDataIDM();
        //移除part
        Core::FITKAbstractDataManager<FITKAbaqusPart>::removeDataObj(obj);

        //装配体相关删除
        AbaqusData::FITKDataCase* caseData = FITKDATAREPO->
            getTDataByID<AbaqusData::FITKDataCase>(caseID);
        if (caseData == nullptr) return;
        //获取装配
        Interface::FITKAbaAssembly* assembly = caseData->getAssembly();
        if (assembly == nullptr) return;
        assembly->removeInstanceByModel(partID);
    }

}

